#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# Copyright (c) 2007 Daniele Favara <nomed@dsslive.org>.
#
# This is free software you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# This software is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this software; see the file COPYING.  If not, write to the Free
# Software Foundation, Inc., 51 Franilin St, Fifth Floor, Boston, MA


import sys, os, smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate, formataddr, make_msgid
from email import Encoders

class Mailer(object):
    def __init__(self, server,user,password,
                 mail_from,mail_to,mail_subject,mail_body,
                 smtp_port=25,smtp_tls=None,smtp_debuglevel=0,mail_from_name=None):

        #SMTP
        self._server = server
        self._user = user
        self._password = password
        self._debuglevel = smtp_debuglevel
        self._port = smtp_port
        self._tls = smtp_tls

        #MAIL
        self._mail_from = mail_from
        self._mail_from_name = mail_from_name
        self._mail_to = mail_to # list
        self._mail_subject = mail_subject
        self._mail_body = mail_body
        self._smtp = smtplib.SMTP()
        self._msg = MIMEMultipart()

    def _get_debuglevel(self):
        return self._debuglevel

    debuglevel = property(_get_debuglevel)

    def _get_server(self):
        return self._server

    server = property(_get_server)

    def _get_password(self):
        return self._password

    password = property(_get_password)

    def _get_user(self):
        return self._user

    user = property(_get_user)

    def _get_tls(self):
        return self._tls

    tls = property(_get_tls)

    def _get_smtp(self):
        return self._smtp

    smtp = property(_get_smtp)


    def _get_mail_from(self):
        return self._mail_from

    mail_from = property(_get_mail_from)

    def _get_mail_from_name(self):
        return self._mail_from_name

    mail_from_name = property(_get_mail_from_name)

    def _get_mail_to(self):
        return COMMASPACE.join(self._mail_to)

    mail_to = property(_get_mail_to)

    def _get_mail_subject(self):
        return self._mail_subject

    mail_subject = property(_get_mail_subject)

    def _get_mail_body(self):
        return self._mail_body

    mail_body = property(_get_mail_body)

    def _get_mail_addr(self):
        if self.mail_from_name:
            self._mail_addr = formataddr((self.mail_from_name, self.mail_from))
        else:
            self._mail_addr = self.mail_from
        return self._mail_addr

    mail_addr = property(_get_mail_addr)

    def _get_msg(self):
        self._msg['From'] = self.mail_addr
        self._msg['To'] = self.mail_to
        self._msg['Date'] = formatdate()
        self._msg['Message-ID'] = make_msgid('tginvoice-nomed')
        self._msg['Subject'] = self.mail_subject
        self._msg.preamble = 'You will not see this in a MIME-aware mail reader.\n'
        # Fa in modo che il messaggio termini con un fine riga
        self._msg.epilogue = ''
        self._msg.attach( MIMEText(self.mail_body) )
        return self._msg

    msg = property(_get_msg)

    def connected(self):
        """Return the current SMTP connection status."""

        return getattr(self.smtp, 'sock', None) is not None

    connected = property(connected)

    def connect(self):
        self.smtp.debuglevel = self.debuglevel

        self.smtp.connect(self.server)

        # try to do tls
        self.smtp.ehlo()
        if self.smtp.has_extn('starttls'):
            self.smtp.starttls()
            self.smtp.ehlo()
            self._tls = True

    def disconnect(self):
        """Disconnect from the SMTP server if connected."""

        if self.connected:
            self.smtp.quit()

    def login(self):
        """
        (235, 'Authentication successful')
        """
        try:
            return self.smtp.login(self.user, self.password)

        except smtplib.SMTPAuthenticationError, e:
            return (e.smtp_code, e.smtp_error)

    def send(self):
        self.connect()
        self.login()
        self.smtp.sendmail(self.mail_addr, self.mail_to, self.msg.as_string())

def main():
    import cgi
    import cgitb; cgitb.enable()  # for troubleshooting

    print "Content-type: text/html"
    print

    print """
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>

    <head>
        <title>Mailer CGI Script</title>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
        <style type="text/css">
            .error {color: red}
        </style>
    </head>

    <body>

      <h3> Mailer CGI Script </h3>
    """



    form = cgi.FieldStorage()

    validate = ['smtp.server',
                'smtp.user',
                'smtp.password',
                'mail.subject',
                'mail.body',
                'mail.from',
                'mail.to']


    has_post = False

    error = '<span class="error">Please insert a value</span>'


    values = {}
    for field in validate:
        values[field] = ''
        if form.has_key(field):
            has_post = True

    for field in validate:
        if has_post:
            values["%s.error" %(field)] = error
        else:
            values["%s.error" %(field)] = ''



    for field in form.keys():
        field_error = "%s.error" %(field)
        if form.has_key(field):
            if type(form[field]) ==  type([]):
                value = form.getlist(field)
            else:
                value = form[field].value

            values[field] = value

            if value:
                values[field_error] = ''

    sendme = True

    for field in validate:
        field_error = "%s.error" %(field)
        if values[field_error]:
            sendme = False
            break

    if has_post and sendme:
        mailer = Mailer(values['smtp.server'],
                        values['smtp.user'],
                        values['smtp.password'],
                        values['mail.from'],
                        [values['mail.to']],
                        values['mail.subject'],
                        values['mail.body']
                        )
        mailer.send()

        print "<pre>Mail Sent"

        print mailer.msg.as_string()

        print "</pre>"

    else:
        print """

            <form method="post" action="mailer.cgi">
                <h4>SMTP SERVER</h4>
                <table>
                    <tr>
                        <th>server: </th>
                        <td><input type="text" name="smtp.server" value="%(smtp.server)s" size="30"/><span>%(smtp.server.error)s</span></td>
                    </tr>
                    <tr>
                        <th>user: </th>
                        <td><input type="text" name="smtp.user" value="%(smtp.user)s" size="30"/><span>%(smtp.user.error)s</span></td>
                    </tr>
                    <tr>
                        <th>password: </th>
                        <td><input type="password" name="smtp.password" value="%(smtp.password)s" size="30"/><span>%(smtp.password.error)s</span></td>
                    </tr>
                </table>
                <h4>MAIL</h4>
                <table>
                    <tr>
                        <th>from: </th>
                        <td><input type="text" name="mail.from" value="%(mail.from)s" size="30"/><span>%(mail.from.error)s</span></td>
                    </tr>
                    <tr>
                        <th>to: </th>
                        <td><input type="text" name="mail.to" value="%(mail.to)s" size="30"/><span>%(mail.to.error)s</span></td>
                    </tr>
                    <tr>
                        <th>subject: </th>
                        <td><input type="text" name="mail.subject" value="%(mail.subject)s" size="30"/><span>%(mail.subject.error)s</span></td>
                    </tr>
                    <tr>
                        <th>body: </th>
                        <td>
                            <p>%(mail.body.error)s</p>
                            <textarea name="mail.body" rows="10" cols="80">%(mail.body)s</textarea>
                        </td>
                    </tr>
                </table>
                <input name="action" value="Send" class="button" type="submit" />
            </form>
        """%(values)
    print """
        </body>
        </html>
    """

if __name__ == '__main__':
    main()